I obtained the Chicago Police Department’s gang database from ProPublica. It’s dataset of people who CPD has classified as gang members. However, it was found to be full of errors and inaccuracies, including outdated information like supposedly-active elderly gang members.

Here, I’m making this gang data into a choropleth map of Chicago, which will display shading based on the number of individuals classified as gang members in each of Chicago’s police beats.

This map provides an accessible way to display how many people were put into the database and the police beat under which they were classified.

Note: I’ve gone with “Number of Arrests” as a shorthand for how many individuals were classified as being in a gang, although the data only indicates the date they were entered into the system and associated with a particular police beat, which may or may not be due to an arrest.

Read in the CPD Gang Database & police beat shape file

This reads in our data that includes the suspected gang member arrest data, police beat in which the arrest occured, the gang affliation, and the age and race of the suspect. The data goes from March 1999 – March 2018.

Then we read in the shapefile of the CPD police beats, so we can map them.

df_gang_318 <- read_excel("CPD Gang Data/CPD gang database 3-18.xlsx", sheet=1)

# I downloaded the Chicago Police Beats Shapefile from the Chicago data portal
map_filepath <- "Boundaries_Police Beats/geo_export_CPD_BEATS.shp"
cpd_beats <- st_read(map_filepath)
## Reading layer `geo_export_CPD_BEATS' from data source `/Users/PrincessO/code/CPD Gang database/Boundaries_Police Beats/geo_export_CPD_BEATS.shp' using driver `ESRI Shapefile'
## Simple feature collection with 277 features and 4 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: -87.94011 ymin: 41.64455 xmax: -87.52414 ymax: 42.02303
## epsg (SRID):    4326
## proj4string:    +proj=longlat +ellps=WGS84 +no_defs
#cleaning the data -- take out any rows with NA for a police beat since we can't map those 

df_gangs <- filter(df_gang_318, !is.na(O_BEAT))
cpd_beats <- filter(cpd_beats, !is.na(beat_num))

Taking a quick look at the Police beats shapefile

This preliminary map includes a popup of the police beat.

#this is just a quick map to map the police beats 

cpd_beats %>% 
  leaflet() %>% 
  addTiles() %>% 
  addPolygons(popup=~beat_num)

Joining the dataframes and creating a new summary for the map

After joining the dataframes, I created a new dataframe from it with a summary of the number of arrests per police beat (num_arrests).

# it looks like df_gangs needs a padded 0 in front of some of the numbers to make them 4 digits instead of 3. So let's clean that up before we join it with cpd_beats (which is all 4 digits)

df_gangs$O_BEAT <- str_pad(df_gangs$O_BEAT, 4, pad = "0")

#inner join the two data frames. Used an inner join to drop any rows where the two police beat numbers didn't match up

cpd_beats_gangs<- inner_join(cpd_beats, df_gangs, by=c('beat_num'='O_BEAT'))


#get the number of arrests per police beat and create a new data frame (CPD_gang_map2) with just that info

CPD_gang_map2 <- cpd_beats_gangs %>%
  group_by(beat_num) %>%
  summarize(num_arrests=n()) 

Ploting the CPD data

Darker blue areas indicate more gang classifications. Select the community area to view a popup of the police beat and the number of arrests.

#set the color pallette as Blues. 

col_pal <- colorNumeric("Blues", domain=CPD_gang_map2$num_arrests)

#Add the pop-up text with Police Beat and Number of Arrests in that area
popup_sb <- paste0("Police Beat: ", as.character(CPD_gang_map2$beat_num), "<br>Number of arrests: ", as.character(CPD_gang_map2$num_arrests))


# yaassss the following leaflet worked! 

leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(-87.628598, 41.855372, zoom = 10) %>% 
  addPolygons(data = CPD_gang_map2, 
              fillColor = ~col_pal(CPD_gang_map2$num_arrests), 
              fillOpacity = 0.7, 
              weight = 0.2, 
              smoothFactor = 0.2, 
              popup = ~popup_sb) %>%
  addLegend(pal = col_pal, 
            values = CPD_gang_map2$num_arrests, 
            position = "bottomright", 
            title = "Number of Arrests")